//
//  ITLocationManager.m
//  ITBE
//
//  Created by ITBE on 2019/3/8.
//  Copyright © 2019 ITBE. All rights reserved.
//

#import "ITLocationManager.h"
#import <CoreLocation/CoreLocation.h>
#import "ITNetworkMonitorManager.h"
#import "ITAppStartManager.h"

#import <sys/utsname.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTCellularData.h>
#import <SystemConfiguration/CaptiveNetwork.h>
#import "mach/mach.h"

#include "dlfcn.h"
#include <sys/stat.h>

@interface ITLocationManager()<CLLocationManagerDelegate>
{
    CLLocationManager *locationManager;
    NSString *lng;
    NSString *lat;
    
    NSString *deviceModel;
    NSString *system;
    NSString *systemVersion;
    NSString *channel;
    NSString *uniqueId;
    NSString *version;

    NSString *language;
    NSString *macAddress;
    
    NSString *userAgent;
    
    
    NSString *agentNetWork;
}
@end

@implementation ITLocationManager
+(instancetype)shareManager
{
    static ITLocationManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[ITLocationManager alloc] init];
        [manager startLocationService];
    });
    return manager;
}

-(void)startLocationService
{

    system = [[UIDevice currentDevice] systemName];
    deviceModel = [ITDeviceInfo deviceModelName];
    systemVersion = [[UIDevice currentDevice] systemVersion];
    channel = @"AppStore";
    macAddress = @"";
    uniqueId = [[ITUserManager shareManager] getDeviceToken];
    version = [ITDeviceInfo appVersion];
    language = [ITDeviceInfo language];
    lat = @"";
    lng = @"";
    
//    if ([CLLocationManager locationServicesEnabled]) {
//        locationManager = [[CLLocationManager alloc] init];
//        [locationManager requestAlwaysAuthorization];
//        [locationManager requestWhenInUseAuthorization];
//        locationManager.delegate = self;
//        locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//        locationManager.distanceFilter = 100.0f;
//        [locationManager startUpdatingLocation];
//    }
}

-(NSString *)returnUserAgent
{
    if (userAgent) {
        return userAgent;
    }
    int timeZone = [[NSTimeZone localTimeZone] secondsFromGMT]/3600;
    NSString *lan = [ITDeviceInfo language];
    NSString *country = [[NSLocale currentLocale] objectForKey:NSLocaleCountryCode];
    userAgent = [NSString stringWithFormat:@"ios/%@/%@/%@/%@/V%@/%d/%@/%@/%@/%@/%@/%@/%d/%@/%@",system,systemVersion,uniqueId,deviceModel,version, Version_Code,[[ITNetworkMonitorManager shareManager] networkName],channel,country,macAddress,lng,lat,timeZone, lan, ITDeviceInfo.getBundleDisplayName];
    return userAgent;
}

-(NSString *)returnNetWorkAgent{
    NSString *carrier = [ITLocationManager getCarrierName];
    BOOL isVpn = NO;
    NSString *proxyInfo = @"";
#if DEBUG
#else
    isVpn = [ITLocationManager isVPNConnected];
    proxyInfo = [ITLocationManager proxyInfo];
#endif
    bool isJb = [ITLocationManager isJB];
    agentNetWork = [NSString stringWithFormat:@"%@/%d/%@/%d", carrier, isVpn, proxyInfo, isJb];
    return agentNetWork;
}

-(NSString *)returnSignString:(NSDate *)time
{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyyMMddHHmmss"];
    [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"Asia/Kolkata"]];
    NSString *timeString = [formatter stringFromDate:time];
    NSString *signString = [NSString stringWithFormat:@"%@%@%@%@%@V%@%@%@",@"ios",system,systemVersion,deviceModel,uniqueId,version,macAddress,timeString];
    return [signString md5String];
}

#pragma -mark CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray<CLLocation *> *)locations
{
    CLLocation *loctaion = [locations firstObject];
    if (loctaion) {
        lng = [NSString stringWithFormat:@"%.2lf",loctaion.coordinate.longitude];
        lat = [NSString stringWithFormat:@"%.2lf",loctaion.coordinate.latitude];
    }
}

- (void)locationManager:(CLLocationManager *)manager
       didFailWithError:(NSError *)error
{
    lng = @"";
    lat = @"";
}

#pragma mark - netinfo

static NSMutableDictionary *_deviceHeaderInfo = nil;
//设备信息
+ (NSDictionary *)deviceHeaderInfo{
    if (_deviceHeaderInfo != nil) {
        return _deviceHeaderInfo;
    }
    NSMutableDictionary *info = [NSMutableDictionary new];
    info[@"GK-Device-Name"] = [[UIDevice currentDevice].name stringByURLEncode];
    info[@"GK-Carrier-Name"] = [self getCarrierName];
#if DEBUG
    //info[@"GK-Use-VPN"] = [self isVPNConnected] ? @"1" : @"0";
    //info[@"GK-Proxy-Info"] = [self proxyInfo];
#else
    info[@"GK-Use-VPN"] = [self isVPNConnected] ? @"1" : @"0";
    info[@"GK-Proxy-Info"] = [self proxyInfo];
    int timeZone = [[NSTimeZone localTimeZone] secondsFromGMT]/3600;
    info[@"GK-Timezone"] = @(timeZone).stringValue;
#endif
    
    info[@"IT-Jail-Break"] = [self isJB] ? @"1" : @"0";
    info[@"GK-Device-Lan"] = [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode];
    _deviceHeaderInfo = info;
    NSLog(@"deviceHeaderInfo:%@",info);
    return _deviceHeaderInfo;
}

+ (NSString *)wifiSSID{
    NSString *ssid = @"";
    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    for (NSString *ifnam in ifs) {
        NSDictionary *info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifnam);
        if (info[@"SSID"]) {
            ssid = info[@"SSID"];
            break;
        }
    }
    return ssid;
}

/**
 判断是否使用代理
 */
+ (NSString *)proxyInfo {
    NSDictionary *proxySettings =  (__bridge NSDictionary *)(CFNetworkCopySystemProxySettings());
    
    NSLog(@"%@", proxySettings);
    
    NSArray *proxies = (__bridge NSArray *)(CFNetworkCopyProxiesForURL((__bridge CFURLRef _Nonnull)([NSURL URLWithString:@"http://www.baidu.com"]), (__bridge CFDictionaryRef _Nonnull)(proxySettings)));
    NSDictionary *settings = [proxies objectAtIndex:0];
    if ([[settings objectForKey:(NSString *)kCFProxyTypeKey] isEqualToString:@"kCFProxyTypeNone"]){
        NSLog(@">>>>>>没有设置代理");
        return @"";
    }else{
        NSString *host = [settings objectForKey:(NSString *)kCFProxyHostNameKey];
        NSString *port = [settings objectForKey:(NSString *)kCFProxyPortNumberKey];
        NSString *type = [settings objectForKey:(NSString *)kCFProxyTypeKey];
        NSString *proxyStr = [NSString stringWithFormat:@"%@:%@:%@",type, host, port];
        NSLog(@">>>>>>设置了代理%@",proxyStr);
        return proxyStr;
    }
}

/**
 判断是否使用VPN
 */
+ (BOOL)isVPNConnected {
    NSDictionary * proxySettings = (__bridge NSDictionary *)CFNetworkCopySystemProxySettings();
    
    NSLog(@"%@", proxySettings);
    
    NSArray * keys = [proxySettings[@"__SCOPED__"] allKeys];
    for (NSString * key in keys) {
        if ([key rangeOfString:@"tap"].location != NSNotFound ||
            [key rangeOfString:@"tun"].location != NSNotFound ||
            [key rangeOfString:@"ppp"].location != NSNotFound) {
            NSLog(@">>>>>>开启了VPN");
            return YES;
        }
    }
    NSLog(@">>>>>>没有开启VPN");
    return NO;
}

/**获取本机运营商名称*/
+ (NSString*) getCarrierName
{
    if (TARGET_IPHONE_SIMULATOR == 1 && TARGET_OS_IPHONE == 1){
        return @"";
    }
    CTTelephonyNetworkInfo *info = [[CTTelephonyNetworkInfo alloc] init];
    
    CTCarrier *carrier = [info subscriberCellularProvider];
    
    //当前手机所属运营商名称
    
    NSString *mobile;
    
    //先判断有没有SIM卡，如果没有则不获取本机运营商
    
    if (!carrier.isoCountryCode) {
        NSLog(@"noSIM");
        mobile = @"";
    }else{
        mobile = [NSString stringWithFormat:@"%@%@",carrier.mobileCountryCode, carrier.mobileNetworkCode];
    }
    //mobile = @"CMCC123";
    return mobile;
}

+ (BOOL)isJB
{
    static BOOL isJailBreak = NO;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSArray *paths = @[@"/Applications/Cydia.app",
                           @"/Library/MobileSubstrate/MobileSubstrate.dylib",
                           @"/usr/lib/system/libsystem_kernel.dylib",
                           @"/usr/sbin/sshd",
                           @"/usr/libexec/ssh-keysign",
                           @"/etc/apt",
                           @"/etc/ssh/sshd_config",
                           @"/var/lib/cydia/",
                           @"/var/cache/apt",
                           @"/var/lib/apt",
                           @"/bin/bash",
                           @"/bin/sh",
                           
        ];
        for (NSString *path  in paths) {
            if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
                isJailBreak = YES;
                break;
            }
        }
        
        //防hook NSFileManager的方法  使用stat系列函数检测Cydia等工具，路径同上
        struct stat stat_info;
        if (0 == stat("/Applications/Cydia.app", &stat_info)) {
            NSLog(@"Device is jailbroken");
            isJailBreak = YES;
        }
        
        //检测stat是否出自系统库
        int ret;
        Dl_info dylib_info;
        int (*func_stat)(const char *,struct stat *) = stat;
        if ((ret = dladdr(func_stat, &dylib_info))) {
            if (strcmp(dylib_info.dli_fname,"/usr/lib/system/libsystem_kernel.dylib") != 0) {
                isJailBreak = YES;
            }
        }
        
        //检测当前程序运行的环境变量，防止通过DYLD_INSERT_LIBRARIES注入链接异常动态库，来更改相关工具名称
        char *env = getenv("DYLD_INSERT_LIBRARIES");
        NSLog(@"%s", env);
        if (env) {
            isJailBreak = YES;
        }
    });
    
    return isJailBreak;
}
@end
